package com.whatever.lottery.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;


public class LotUtils {
	
	public static int getChoose(int n, int m) {
		if (m > n | m < 0 | n < 0) {
			return 0;
		}
		if (m < n / 2.0) {
			m = n - m;
		}
		double s1 = 0;
		for (int i = m + 1; i <= n; i++) {
			s1 += Math.log((double) i);
		}
		double s2 = 0;
		int ub = n - m;
		for (int i = 2; i <= ub; i++) {
			s2 += Math.log((double) i);
		}

		Double s = new Double(Math.round(Math.exp(s1 - s2)));
		if (s > Integer.MAX_VALUE) {
			return 0;
		} else {
			return s.intValue();
		}
	}
	
	public static int getExactHitCount(int danHit,int tuoHit,int danLen,int tuoLen,int bitLen,int mustHit){
		if (danLen > bitLen){
			return 0;
		}
		
		int tuoInLen = bitLen - danLen;
		if (danHit > mustHit){
			return 0;
		}
		
		if (danHit == mustHit){
			return getChoose(danHit, mustHit) * getChoose(tuoLen - tuoHit, tuoInLen);
		}
		
		int tuoMustHit = mustHit - danHit;
		if (tuoHit < tuoMustHit){
			return 0;
		}		
		
		if (tuoInLen < tuoMustHit){
			return 0;
		}				
		
		return getChoose(tuoHit, tuoMustHit) * getChoose(tuoLen - tuoHit, tuoInLen - tuoMustHit);
	}

	private static boolean[] copyOf(boolean[] arr) {
		boolean[] ret = new boolean[arr.length];
        System.arraycopy(arr, 0, ret, 0, arr.length);
        return ret;
    }
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List getComList(List<T> list,int m){
		List ret = new ArrayList();
		List<boolean[]> listArrBit = getComArrBit(list.size(),m);
		for (boolean[] arrBit: listArrBit){
			List tmp = new ArrayList();
			for(int i=0;i<arrBit.length;i++){
				if (arrBit[i]){
					tmp.add(list.get(i));
				}
			}
			ret.add(tmp);
		}
		return ret;	
	}
	
	public static List<boolean[]> getComArrBit(int n, int m) {
		List<boolean[]> ret = new ArrayList<boolean[]>();
		
		if (m > n) {
			return ret;
		}
		
		if (m == 0) {
			return ret;
		}
		
		boolean[] bs = new boolean[n];

		for (int i = 0; i < m; i++) {
			bs[i] = true;
		}

		boolean flag = true;
		boolean tempFlag = false;
		int pos = 0;
		int sum = 0;

		do {
			sum = 0;
			pos = 0;
			tempFlag = true;
			
			ret.add(copyOf(bs));
			
			if (n == m)
				return ret;
			
			for (int i = 0; i < n - 1; i++) {
				if (bs[i] && !bs[i + 1]) {
					bs[i] = false;
					bs[(i + 1)] = true;
					pos = i;
					break;
				}
			}

			for (int i = 0; i < pos; i++) {
				if (bs[i]) {
					sum++;
				}
			}
			
			for (int i = 0; i < pos; i++) {
				if (i < sum)
					bs[i] = true;
				else {
					bs[i] = false;
				}
			}

			for (int i = n - m; i < n; i++) {
				if (!bs[i]) {
					tempFlag = false;
					break;
				}
			}
			
			if (!tempFlag)
				flag = true;
			else
				flag = false;
			
		} while (flag);

		ret.add(copyOf(bs));
		
		return ret;
	}
	
	public static double getScale(double src,int scale){
		BigDecimal bd = new BigDecimal(src); 
		return bd.setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	public static List<Integer> getMultiList(int multi,int maxMulti){
		List<Integer> ret = new ArrayList<Integer>();
		
		int lastMulti = multi%maxMulti;
		
		int nMaxMulti = multi/maxMulti;
		
		for(int i=0;i<nMaxMulti;i++){
			ret.add(maxMulti);
		}
		
		if (lastMulti>0){
			ret.add(lastMulti);
		}
		return ret;
	}
	
	public static String list2str(List<String> list,String gap){
		StringBuilder sb = new StringBuilder();
		for (String str:list){
			sb.append(str).append(gap);
		}
		if (sb.length()>gap.length()){
			sb.setLength(sb.length()-gap.length());
		}
		return sb.toString();
	}
	
	
}
